<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue框架常用语法测试</title>
    <!-- 引入Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
        }
        .section {
            margin-bottom: 30px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .section h2 {
            font-size: 18px;
            text-align: left;
            width: 180px;
            font-size: 16px;
            margin-top: 0;
        }
        .demo-button {
            background-color: #42b983;
            color: white;
            border: none;
            padding: 8px 16px;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
        .demo-button:hover {
            background-color: #359c6d;
        }
        .completed {
            text-decoration: line-through;
            color: #888;
        }
        input, button {
            padding: 8px;
            margin: 5px;
        }
        ul {
            list-style-type: none;
            padding: 0;
        }
        li {
            padding: 5px 0;
        }
        .todo-item {
            display: flex;
            align-items: center;
            margin: 5px 0;
        }
        .todo-item input[type="text"] {
            flex: 1;
            margin: 0 10px;
        }
        .form-group {
            margin: 10px 0;
        }
        .form-group label {
            display: inline-block;
            width: 100px;
        }
    </style>
</head>
<body>
    <h1 style="font-size: 20px;">Vue框架常用语法测试</h1>
    
    <!-- 1. 文本插值 -->
    <div id="app1" class="section">
        <h2>1. 文本插值</h2>
        <p>消息: {{ message }}</p>
        <p>原始HTML: <span v-html="rawHtml"></span></p>
        <p>表达式: {{ number + 1 }}</p>
        <p>三元表达式: {{ ok ? 'YES' : 'NO' }}</p>
    </div>

    <!-- 2. 条件渲染 -->
    <div id="app2" class="section">
        <h2>2. 条件渲染</h2>
        <button @click="show = !show" class="demo-button">切换显示</button>
        <p v-if="show">你现在看到我了!</p>
        <p v-else-if="show === false">现在你看不到我了!</p>
        <p v-show="show">使用v-show指令: {{ show ? '显示' : '隐藏' }}</p>
    </div>

    <!-- 3. 列表渲染 -->
    <div id="app3" class="section">
        <h2>3. 列表渲染</h2>
        <ul>
            <li v-for="(item, index) in items" :key="index">
                {{ index }} - {{ item.message }}
            </li>
        </ul>
        <ul>
            <li v-for="(value, key, index) in object" :key="key">
                {{ index }}. {{ key }}: {{ value }}
            </li>
        </ul>
        <button @click="addItem" class="demo-button">添加项目</button>
        <button @click="removeItem" class="demo-button">移除项目</button>
    </div>

    <!-- 4. 事件处理 -->
    <div id="app4" class="section">
        <h2>4. 事件处理</h2>
        <p>{{ message }}</p>
        <button @click="reverseMessage" class="demo-button">反转消息</button>
        <button v-on:click="changeMessage('Hello Vue!')" class="demo-button">更改消息</button>
        <button @click="say('hi')" class="demo-button">说 hi</button>
        <button @click="say('what', $event)" class="demo-button">说 what</button>
    </div>

    <!-- 5. 表单输入绑定 -->
    <div id="app5" class="section">
        <h2>5. 表单输入绑定</h2>
        <div class="form-group">
            <label>文本输入:</label>
            <input v-model="message" placeholder="请输入文本">
            <p>输入的文本: {{ message }}</p>
        </div>
        
        <div class="form-group">
            <label>多行文本:</label>
            <textarea v-model="textarea" placeholder="添加多行文本"></textarea>
            <p>多行文本: {{ textarea }}</p>
        </div>
        
        <div class="form-group">
            <label>复选框:</label>
            <input type="checkbox" id="checkbox" v-model="checked">
            <label for="checkbox">{{ checked }}</label>
        </div>
        
        <div class="form-group">
            <label>多选框组:</label>
            <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
            <label for="jack">Jack</label>
            <input type="checkbox" id="john" value="John" v-model="checkedNames">
            <label for="john">John</label>
            <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
            <label for="mike">Mike</label>
            <p>选中的名字: {{ checkedNames }}</p>
        </div>
        
        <div class="form-group">
            <label>单选按钮:</label>
            <input type="radio" id="one" value="One" v-model="picked">
            <label for="one">One</label>
            <input type="radio" id="two" value="Two" v-model="picked">
            <label for="two">Two</label>
            <p>选中的值: {{ picked }}</p>
        </div>
        
        <div class="form-group">
            <label>选择框:</label>
            <select v-model="selected">
                <option disabled value="">请选择</option>
                <option>A</option>
                <option>B</option>
                <option>C</option>
            </select>
            <p>选中的值: {{ selected }}</p>
        </div>
    </div>

    <!-- 6. 计算属性 -->
    <div id="app6" class="section">
        <h2>6. 计算属性</h2>
        <p>原始消息: "{{ message }}"</p>
        <p>计算属性反转消息: "{{ reversedMessage }}"</p>
        <p>方法反转消息: "{{ reversedMessageMethod() }}"</p>
        <p>计算属性缓存: "{{ now }}"</p>
        <button @click="message = 'Hello Vue!'" class="demo-button">更改消息</button>
    </div>

    <!-- 7. 侦听器 -->
    <div id="app7" class="section">
        <h2>7. 侦听器</h2>
        <p>
            <input v-model="question" placeholder="请输入问题">
        </p>
        <p>{{ answer }}</p>
    </div>

    <!-- 8. Class与Style绑定 -->
    <div id="app8" class="section">
        <h2>8. Class与Style绑定</h2>
        <div :class="{ active: isActive }" @click="isActive=!isActive">
            点击切换激活状态
        </div>
        <div class="static" :class="{ active: isActive, 'text-danger': hasError }">
            动态添加多个class
        </div>
        <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
            动态内联样式
        </div>
        <button @click="isActive=!isActive" class="demo-button">切换激活</button>
        <button @click="hasError=!hasError" class="demo-button">切换错误</button>
    </div>

    <!-- 9. 组件基础 -->
    <div id="app9" class="section">
        <h2>9. 组件基础</h2>
        <todo-item 
            v-for="(todo, index) in groceryList" 
            :key="todo.id"
            :todo="todo"
            :title="todo.text"
            @remove="removeTodo"
            :class="{ completed: todo.completed }">
        </todo-item>
        <div class="todo-item">
            <input type="text" v-model="newTodoText" placeholder="添加新项目">
            <button @click="addTodo" class="demo-button">添加</button>
        </div>
    </div>

    <script>
        // 1. 文本插值
        var app1 = new Vue({
            el: '#app1',
            data: {
                message: 'Hello Vue.js!',
                rawHtml: '<span style="color: red">这是原始HTML</span>',
                number: 5,
                ok: true
            }
        })

        // 2. 条件渲染
        var app2 = new Vue({
            el: '#app2',
            data: {
                show: true
            }
        })

        // 3. 列表渲染
        var app3 = new Vue({
            el: '#app3',
            data: {
                items: [
                    { message: 'Foo' },
                    { message: 'Bar' }
                ],
                object: {
                    title: 'Vue指南',
                    author: 'Vue团队',
                    publishedAt: '2020-01-01'
                }
            },
            methods: {
                addItem: function() {
                    this.items.push({ message: 'Baz' })
                },
                removeItem: function() {
                    this.items.pop()
                }
            }
        })

        // 4. 事件处理
        var app4 = new Vue({
            el: '#app4',
            data: {
                message: 'Hello Vue.js!'
            },
            methods: {
                reverseMessage: function() {
                    this.message = this.message.split('').reverse().join('')
                },
                changeMessage: function(msg) {
                    this.message = msg
                },
                say: function(message, event) {
                    if (event) {
                        alert(message + ' ' + event.target.tagName)
                    } else {
                        alert(message)
                    }
                }
            }
        })

        // 5. 表单输入绑定
        var app5 = new Vue({
            el: '#app5',
            data: {
                message: '',
                textarea: '',
                checked: false,
                checkedNames: [],
                picked: '',
                selected: ''
            }
        })

        // 6. 计算属性
        var app6 = new Vue({
            el: '#app6',
            data: {
                message: 'Hello'
            },
            computed: {
                // 计算属性的 getter
                reversedMessage: function() {
                    return this.message.split('').reverse().join('')
                },
                now: function() {
                    return Date.now()
                }
            },
            methods: {
                reversedMessageMethod: function() {
                    return this.message.split('').reverse().join('')
                }
            }
        })

        // 7. 侦听器
        var app7 = new Vue({
            el: '#app7',
            data: {
                question: '',
                answer: '请输入问题，以?结尾'
            },
            watch: {
                // 如果 `question` 发生改变，这个函数就会运行
                question: function (newQuestion, oldQuestion) {
                    this.answer = '等待输入...'
                    this.getAnswer()
                }
            },
            methods: {
                getAnswer: function () {
                    if (this.question.indexOf('?') === -1) {
                        this.answer = '问题通常包含一个?'
                        return
                    }
                    this.answer = '思考中...'
                    // 模拟API调用
                    setTimeout(() => {
                        this.answer = '答案是：也许吧'
                    }, 1000)
                }
            }
        })

        // 8. Class与Style绑定
        var app8 = new Vue({
            el: '#app8',
            data: {
                isActive: true,
                hasError: false,
                activeColor: 'red',
                fontSize: 16
            }
        })

        // 9. 组件基础
        Vue.component('todo-item', {
            props: ['todo', 'title'],
            template: `
                <div class="todo-item">
                    <input type="checkbox" v-model="todo.completed">
                    <span :class="{ completed: todo.completed }">{{ title }}</span>
                    <button @click="$emit('remove')">X</button>
                </div>
            `
        })

        var app9 = new Vue({
            el: '#app9',
            data: {
                groceryList: [
                    { id: 0, text: '蔬菜', completed: false },
                    { id: 1, text: '奶酪', completed: true },
                    { id: 2, text: '米饭', completed: false }
                ],
                newTodoText: ''
            },
            methods: {
                removeTodo: function(index) {
                    this.groceryList.splice(index, 1)
                },
                addTodo: function() {
                    if (this.newTodoText.trim() !== '') {
                        const newId = this.groceryList.length > 0 ? 
                            Math.max(...this.groceryList.map(todo => todo.id)) + 1 : 0;
                        this.groceryList.push({
                            id: newId,
                            text: this.newTodoText,
                            completed: false
                        })
                        this.newTodoText = ''
                    }
                }
            }
        })
    </script>
</body>
</html>